package com.cdsxt.base;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cdsxt.util.ClassUtil;
import com.cdsxt.util.SpringUtil;
import com.cdsxt.vo.ResponseResultVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;

/**
 * 
 * @author 成都尚学堂 & mr zeng
 * 客服热线：028-65176856
 * 网址： www.cd-sxt.com
 * 
 * @param <PoCls>传入当前dao层对应的po类型
 */
public abstract  class BaseController<PoCls extends BaseEntity>{
	/**
	 * 服务器对象
	 */
	@Autowired
	protected HttpSession ses;
	@Autowired
	protected HttpServletRequest req;
	@Autowired
	protected HttpServletResponse resp;
	/**
	 * 业务对象
	 */
	
	/**
	 * 通用功能
	 */
	//获取当前用户信息
	public <UserType> UserType getCurUser(){
		UserType user= (UserType) this.ses.getAttribute("curUser");
		return user;
	}
	
	/**
	 * 获取指定cookie的name的val的功能
	 * 并对cookie的值进行url解码
	 */
	public  String getCookieValue(String cookieName) throws Exception{
		
		Cookie[] cookieArr=this.req.getCookies();
		//cookie的值
		String cookieVal=null;
		for (Cookie cookie : cookieArr) {
			if (cookieName.equals(cookie.getName())) {
				cookieVal=cookie.getValue();
				//解码
				cookieVal= URLDecoder.decode(cookieVal, "utf-8");
				
				return cookieVal;
			}
		}
		//找不到对应值返回null
		return null;
	}
	
	
	/**
	 * 删除cookie
	 * @param req
	 * @param resp
	 * @param cookieName
	 */
	public  void deleteCookie(String cookieName){
		Cookie[] cookieArr=this.req.getCookies();
		
		for (Cookie cookie : cookieArr) {
			if (cookieName.equals(cookie.getName())) {
				/**
				 * 注意！新建cookie对象进行删除
				 */
				//删除cookie
				Cookie ck=new Cookie(cookieName, cookie.getValue());
				ck.setMaxAge(0);
				ck.setPath("/");
				//通过resp对象设置到输出的cookie中
				this.resp.addCookie(ck);
				return;
			}
		}
	}
	
	/**
	 * ==================================通用crud===========================================
	 */
	//模块名
	private String moduleName;
	//基础的service这里根据模块名注入了对应的service
	private BaseService<PoCls> baseService;
	
	
	public String getModuleName() {
		if (this.moduleName==null) {
			throw new RuntimeException("当前类没有设置泛型参数不能获取模块名moduleName");
		}
		return moduleName;
	}

	public BaseService<PoCls> getBaseService() {
		if (this.baseService==null) {
			throw new RuntimeException("当前类没有设置泛型参数不能获取模块的service");
		}
		return baseService;
	}

	//baseController初始化方法：
	//定时器
	private static Timer tm =new Timer();
	//@PostConstruct
	public BaseController()  {
		//延时2000执行，防止SpringUtil.getBean拿不到数据
		tm.schedule(new TimerTask() {
			@Override
			public void run() {
				try {
					Class<Object> poCls = ClassUtil.getClassParamType(BaseController.this.getClass());
					moduleName = poCls.getSimpleName().replaceAll("Po", "");
					//模块名
					moduleName= moduleName.substring(0, 1).toLowerCase()+moduleName.substring(1);
					//dao的bean对象的名
					String serviceBeanName=moduleName+"Service";
					//从springbean工厂获取dao的bean
					baseService = (BaseService<PoCls>) SpringUtil.getBean(serviceBeanName);
				} catch (Exception e) {
					e.printStackTrace();
					System.out.println("当前类："+BaseController.this.getClass()+"没有设置泛型参数");
				}
				
			}
		}, 2000);
	}
	
	@RequestMapping("/findAll")
	public String findAll() {
		List<PoCls> list = this.getBaseService().findAll();
		this.req.setAttribute(moduleName+"List", list);
		return "page/"+this.getModuleName()+"/find";
	}
	
	@RequestMapping("/findByPage")
	public String findByPage(@RequestParam(name="start",defaultValue="0") Integer start,
			@RequestParam(name="limit",required=false)  Integer limit) {
			List<PoCls> list = this.getBaseService().findByPage(start, limit);
		this.req.setAttribute(this.getModuleName()+"List", list);

		return "page/"+this.getModuleName()+"/find";
	
	}
	
	@RequestMapping("/findListCusTypeByCondition")
	public String findListCusTypeByCondition(@RequestParam Map<String,Object> params) {
		//空白的值换为null
		params.replaceAll((String key, Object val)->{
			if (val instanceof String) {
				String value = (String) val;
				if (StringUtil.isEmpty(value)) {
					return null;
				}
			}
			return val;
		});
		//设置默认的排序：createDate降序
		String orderByColumn=(String) params.get("orderByColumn");
		if (orderByColumn==null) {
			params.put("orderByColumn", "create_date");
			params.put("orderByDesc", true);

		}
		//默认设置分页数据
		String pageNumStr=(String) params.get("pageNum");
		if (pageNumStr==null) {
			pageNumStr="1";
		}
		int pageNum=Integer.parseInt(pageNumStr);
		int pageSize=10;
		PageHelper.startPage(pageNum, pageSize);
		//查询分页数据
		List<PoCls> list = this.getBaseService().findListCusTypeByCondition(params);
		PageInfo<PoCls> pageInfo=new PageInfo<>(list);
		this.req.setAttribute("pageInfo", pageInfo);
		return "page/"+this.getModuleName()+"/find";
	
	}
	
	@RequestMapping("/save")
	@ResponseBody
	public ResponseResultVo save(PoCls po) {
		System.out.println("LitemallUserController.save()");
		this.getBaseService().save(po);
		return ResponseResultVo.successResult();
	}	
	
	@RequestMapping("/update")
	@ResponseBody
	public ResponseResultVo update(PoCls po) {
		this.getBaseService().update(po);
		return ResponseResultVo.successResult();
	}
	
	@RequestMapping("/goUpdate")
	public String goUpdate(Integer id) {
		PoCls po = this.getBaseService().findOne(id);
		this.req.setAttribute(moduleName, po);
		return "page/"+this.getModuleName()+"/form";
	}
	
	@RequestMapping("/delete")
	public String delete(Integer id) {
		this.getBaseService().delete(id);
		return "forward:/"+this.getModuleName()+"/findListCusTypeByCondition";
	}
	
	@RequestMapping("/findOne")
	@ResponseBody
	public ResponseResultVo findOne(Integer id) {
		return ResponseResultVo.successResult(this.getBaseService().findOne(id));
	}
}
